package com.cie2.janji.services;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.joda.time.DateTime;
import org.joda.time.Interval;

import com.cie2.janji.entities.Promise;
import com.cie2.janji.entities.Promise.PromiseStatus;

public class PromiseEngine {

	private Session session;

	public PromiseEngine(Session session) {
		this.session = session;
	}

	public void updateStatus(PromiseStatus status, Promise promise) {
		// should check the previous status, so there's a state diagram ? 

		if (promise.getStatus().equals(PromiseStatus.Unrealized)) {
			if (status.equals(PromiseStatus.Keep)) {

			} else if (status.equals(PromiseStatus.Broken)) {

			} else if (status.equals(PromiseStatus.Extended)) {

			}
		} else if (promise.getStatus().equals(PromiseStatus.Extended)) {
			if (status.equals(PromiseStatus.Keep)) {

			} else if (status.equals(PromiseStatus.Broken)) {

			}

		}

		promise.setUpdatedDate(new Date());
		promise.setStatus(status);
		session.persist(promise);
	}

	/**
	 * method is executed by scheduler that run each day (aprox 1 AM)
	 * 
	 * If a promise end date has passed , than this method will update the promise status into broken.
	 *
	 */
	public void updateStatusDailyJob() {

		List myList = session.createCriteria(Promise.class)
			.add(Restrictions.ne("status", Promise.PromiseStatus.Keep ))
			.add(Restrictions.ne("status", Promise.PromiseStatus.Broken ))			
			.addOrder(Order.desc("createdDate"))
			.addOrder(Order.desc("startDate"))
			.list();

		int brokenPromise = 0;
		
		session.beginTransaction();
		DateTime today = new DateTime();

		for (Iterator iter = myList.iterator(); iter.hasNext();) {
			Promise promise = (Promise) iter.next();
			
			DateTime endDT = new DateTime(promise.getEndDate());			
			DateTime startDT = new DateTime(promise.getStartDate());
			
			// using dt.isBeforeNow will compare the 'end date' with current time in milisecond, in other words
			// if we schedule the process to run every day at 1 AM. That means that promise
			// that was created at 12.01 will be treated as expired, although the day has passed
			// lets use a consensus that no one will create a promise at 12.01 - 01.00 AM each day :)
			// if needed this can be fixed, but now is not the time
			if(endDT.isBeforeNow()) {
				promise.setStatus(Promise.PromiseStatus.Broken);
				brokenPromise++;
			}
			else if(startDT.isBeforeNow()) {
				Interval elapsed = new Interval(startDT, today);
				Interval total = new Interval(startDT, endDT);
				
				long elapsedMili = elapsed.toDuration().getStandardSeconds() ;
				long totalMili = total.toDuration().getStandardSeconds();
	
				long percentage = elapsedMili*100/totalMili;
				
				if(percentage > 0 && promise.getPercentage().intValue() != 25) {
					promise.setPercentage(25);
				}
				else if (percentage > 25 && promise.getPercentage().intValue() != 50) {
					promise.setPercentage(50);
				}
				else if (percentage > 50 && promise.getPercentage().intValue() != 75) {
					promise.setPercentage(75);
				} else if (percentage > 75 && promise.getPercentage().intValue() != 100){
					promise.setPercentage(100);
				}
				
			}			
			session.update(promise);
			
		}
		
		session.getTransaction().commit();
	}
}
